#include <stdlib.h>

#include "lib.h"

#include "slotguts.h"
#include "bonkguts.h"
#include "slotspin.h"
#include "getrand.h"

enum WheelContents {
    BLANK,
    BONKER,
    BAR1,
    BAR2,
    BAR3,
    SEVEN,
};


enum SpinResult
{
	EVT_LOSER = 0,
	EVT_1BONKER,
	EVT_2BONKERS,
	EVT_3BONKERS,
	EVT_ANY3BAR,
	EVT_3BAR1,
	EVT_3BAR2,
	EVT_3BAR3,
	EVT_3SEVENS,
	NUMEVENTS
};


enum RESPINS
{
    RESPIN_1BONKER = 0,
    RESPIN_2BONKERS = 3,
    RESPIN_3BONKERS = 10
};

bool8 
BonkSlotGuts::isValidGuts()
{
    return getGutsId() == 500 ||
           getGutsId() == 501 ||
           getGutsId() == 502 ||
           getGutsId() == 503 ||
           getGutsId() == 504 ||
           getGutsId() == 505 ||
           getGutsId() == 506 ||
           getGutsId() == 507;
}

void
BonkSlotGuts::spin(SlotSpin *slotSpin)
{
    SlotGuts::spin(slotSpin);
    uint8 respins = 0;
    SpinLine *spinLine = slotSpin->getSpinLineAt(0);
	SlotSpin *winspin = (SlotSpin*) 0;

    // Check for Bonkers.
    if ( spinLine->payouttypeid == EVT_1BONKER )
    {
        respins = RESPIN_1BONKER;
    }
    else if ( spinLine->payouttypeid == EVT_2BONKERS )
    {
        respins = RESPIN_2BONKERS;
    }
    else if ( spinLine->payouttypeid == EVT_3BONKERS )
    {
        respins = RESPIN_3BONKERS;
    }

    for ( int i = 0; i < respins; i++ )
    {
		winspin = new SlotSpin();

        winspin->setBet(slotSpin->getBet());
        winspin->setBonusGameType(0);
        winspin->addLine(1);

        makeWinningSpin(winspin);
    }

}

uint8
BonkSlotGuts::classifyStops(uint8* stops,uint8 bet, uint8 line)
{
	uint8 result = EVT_LOSER;
    int numBonkers = 0;
    int numSevens = 0;
    int numBar1 = 0;
    int numBar2 = 0;
    int numBar3 = 0;
    int numBars = 0;

    //  Do a preliminary run-through
    for ( int i = 0; i < getReelCount(); i++ )
    {
        // Set the icon flags;
        switch ( getIcon(i, stops[i])->iconid )
        {
            case BONKER:
                numBonkers++;
                break;

            case SEVEN:
                numSevens++;
                break;

            case BAR1:
                numBar1++;
                numBars++;
                break;

            case BAR2:
                numBar2++;
                numBars++;
                break;

            case BAR3:
                numBar3++;
                numBars++;
                break;
        }
    }


    //  EVT_3SEVENS ** Jackpot **
    if ( numSevens == 3 )
    {
        result = EVT_3SEVENS;
    }
    else
    {

        // EVT_3BAR1
        if ( result == EVT_LOSER && numBar1 ==3 )
        {
            result = EVT_3BAR1;
        }

        // EVT_3BAR2
        if ( result == EVT_LOSER && numBar2 == 3 )
        {
            result = EVT_3BAR2;
        }

        // EVT_3BAR3
        if ( result == EVT_LOSER && numBar3 == 3 )
        {
            result = EVT_3BAR3;
        }

        // EVT_ANY3BARS     -  Must be checked after the bar triplets
        if ( result == EVT_LOSER && numBars == 3 )
        {
            result = EVT_ANY3BAR;
        }

        // EVT_1BONKER
        // EVT_2BONKERS
        //
        if ( result == EVT_LOSER && numBonkers > 0 )
        {
            if ( numBonkers == 3 )
            {
                result = EVT_3BONKERS;
            }
            else if ( numBonkers == 2 )
            {
                result = EVT_2BONKERS;
            }
            else
            {
                result = EVT_1BONKER;
            }
        }

    }




	return result;
}


void 
BonkSlotGuts::makeWinningSpin(SlotSpin *spin)
{
    uint8 *stops = new uint8[getReelCount()];

    /**
     * Spin until we get a winner.
     */
    while ((spin->getTotalPayoutAmount() == 0 ) && (!spin->getJackpot()))
    {
			for ( uint8 i = 0; i < getReelCount() ; i++)
			{
				stops[i] = this->findPositionByWeight(getrand(), i);
			}
			spin->setStops(getReelCount(), stops);
			classifyResult(spin);
		
    }
	spin->setBet(0);
    spin->setSpinComplete(true);
    m_spins.push_back(spin);

#ifdef DEBUGVERBOSE
	DEBUGMSG(("MakeWinningSpin - Spin: bet(%d) payout(%d) jackpot(%d)",
              spin->getTotalBet(), spin->getTotalPayoutAmount() / m_info->creditValue, spin->getJackpot()));
    for ( uint8 reelid = 0; reelid < getReelCount(); reelid++ )
    {
        DEBUGMSG(("                     wheel %d: [%s])",
                  reelid, 
                  getIcon(reelid, spin->getStops()[reelid])->iconName));
    }
#endif

    delete [] stops;

}


